package cn.wy.basic.service.impl;

import cn.wy.basic.dto.CodeDto;
import cn.wy.basic.service.VerifyService;
import cn.wy.basic.util.SmsUtils;
import cn.wy.basic.util.StrUtils;
import cn.wy.basic.util.VerifyCodeUtils;
import cn.wy.exception.BusinessException;
import cn.wy.user.domain.User;
import cn.wy.user.mapper.UserMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.CrossOrigin;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyServiceImpl implements VerifyService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Override
    public String getImgCode(String key) {

        //获取随机验证码
        String code = VerifyCodeUtils.generateVerifyCode(4);
        //String code = StrUtils.getComplexRandomString(4);

        //将验证码存放到redis，设置5分钟过期
        redisTemplate.opsForValue().set(key, code, 5, TimeUnit.MINUTES);

        //把验证码的值合并到图片，使用Base64编码。并返回base64编码的字符串
        System.out.println(key+"======="+code);
        return VerifyCodeUtils.verifyCode(115, 40, code);
    }

    @Override
    public void getsmsCode(Map<String, String> map) {
        String phone = map.get("phone");
        String imageCode = map.get("imageCode");
        String imgCodeKey = map.get("imageCodeKey");
        //1、验证手机号和图形验证码是否为空
        if(StringUtils.isEmpty(phone)||StringUtils.isEmpty(imageCode)){
            throw new BusinessException("信息不能为空,请输入后重试！！！");
        }
        //2、验证图形验证码是否过期,是否正确
        //获取后端图形验证码
        Object obj = redisTemplate.opsForValue().get(imgCodeKey);

        if(obj==null){
            throw new BusinessException("图形验证码已过期");
        }
        if(!imageCode.equalsIgnoreCase(obj.toString())){
            throw new BusinessException("图形验证码错误");
        }
        //3、验证手机号是否重复
        User user = userMapper.findOneByPhone(phone);
        if(user!=null){
            throw new BusinessException("该手机号已注册，请直接登录!");
        }
        //从Redis获取手机验证码【register:18566565555 - 9527:1555566666666】
        Object phoneCode = redisTemplate.opsForValue().get("register:"+phone);
        String code= null;
        if(phoneCode==null){
            code=StrUtils.getRandomString(4);
        }else {
            long timeMillis = System.currentTimeMillis();
            long oldtime = Long.parseLong(phoneCode.toString().split(":")[1]);
            if((timeMillis-oldtime)<1*60*1000){
                throw new BusinessException("请勿重复发送验证码");
            }
            code=phoneCode.toString().split(":")[0];
        }
        //将手机验证码保存到Redis里面，过去时间为3分钟
        redisTemplate.opsForValue().set("register:"+phone,code+":"+System.currentTimeMillis(),
                3,TimeUnit.MINUTES);
        //SmsUtils.sendSms(phone,"验证码:"+code+",请在3分钟内使用!");
        System.out.println("验证码:"+code+",请在3分钟内使用!");
    }

    /**
     * 微信登录验证码
     * @param codeDto
     */
    @Override
    public void binderVerifyCode(CodeDto codeDto) {
        String phone = codeDto.getPhone();
        //一：校验：空值校验 - 前端和后端都可以校验手机格式问题
        if(StringUtils.isEmpty(phone)){
            throw new BusinessException("信息不能为空!!!");
        }

        //三：校验：手机号码是否注册过
        //两个微信不能绑定一个手机号
        User user = userMapper.findOneByPhone(phone);
        if(user != null){//根据手机号码查到了 = 手机已经注册
            throw new BusinessException("该号码已经绑定过，请直接登陆!!!");
        }

        //四：直接从redis获取手机验证码：key【业务🗡:手机号】
        Object phoneCode = redisTemplate.opsForValue().get("binder:" + phone);
        //1.没有获取到 = 第一次发送或者过期了，调用StrUtils工具类重新生成
        String code = null;//用于保存手机验证码
        if(phoneCode == null){
            code = StrUtils.getRandomString(4);//4位纯数字的验证码
        }else{
            //2.获取到了 = 没有过期，判断重发时间【时间戳 】
            Long oldTime = Long.parseLong(phoneCode.toString().split(":")[1]); //之前的验证码设置的时间戳
            if((System.currentTimeMillis() - oldTime)<1*60*1000){ //1分钟重发时间
                //a.如果没有过重发时间 - 没有重发时间，居然发请求过了 = 违规操作 - 抛异
                throw new BusinessException("操作频繁，稍后重试!!!");
            }else{
                //b.如果过了重发时间 - 可以获取新的验证码【用没有过期的 - code:时间戳】
                code = phoneCode.toString().split(":")[0];
            }
        }

        //五：讲key和验证码保存在redis，重新设置过期时间3分钟【如果是用以前的-这句话就刷新了过期时间】
        redisTemplate.opsForValue().set("binder:" + phone,code+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);
        //六：调用短信的工具类发送短信
        //SmsUtils.sendSms(phone,"你的手机验证码是：" + code +",请在3分钟内使用!!!");
        System.out.println("你的手机验证码是：" + code +",请在3分钟内使用!!!");
    }
}